Repository navigation
Fix legacy casting upgrades, portable MCP config, and CRLF preservation - #2190
Conversation
Preserve historical identities and dates with non-overwriting original archives, strict preflight validation, and recoverable managed-pair publication. Add dry-run, idempotency, interruption, and upgrade-before-writes regressions. Closes #2174 Closes #2182 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: cd73060d-2a21-4bce-b8d6-c7507887dbe7
Use supported PATH executables for standalone project MCP entries, retaining machine-local absolute launch resolution and npm pins. Preserve destination newlines across managed copies, workflow stubs, coordinator capabilities, and shared MCP updates, including byte-preserving backups and newline-only no-op behavior. Closes #2174 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: cd73060d-2a21-4bce-b8d6-c7507887dbe7
🛫 PR Readiness Check
PR Scope: 📦🔧 Mixed (product + infrastructure)
|
| Status | Check | Details |
|---|---|---|
| ❌ | Single commit | 5 commits — consider squashing before review |
| ✅ | Not in draft | Ready for review |
| ✅ | Branch up to date | Up to date with dev |
| ❌ | Copilot review | No Copilot review yet — it may still be processing |
| ✅ | Changeset present | Changeset file found |
| ✅ | Scope clean | No .squad/ or docs/proposals/ files |
| ✅ | No merge conflicts | No merge conflicts |
| ✅ | Copilot threads resolved | All 1 Copilot thread(s) resolved |
| ✅ | CI passing | All checks passing |
Files Changed (28 files, +1732 −65)
| File | +/− |
|---|---|
.changeset/legacy-assignment-provenance.md |
+10 −0 |
.changeset/legacy-casting-upgrade.md |
+6 −0 |
.changeset/portable-mcp-preserve-newlines.md |
+6 −0 |
docs/src/content/docs/features/standalone-install.md |
+16 −4 |
docs/src/content/docs/scenarios/upgrading.md |
+104 −7 |
packages/squad-cli/src/cli/core/init.ts |
+3 −3 |
packages/squad-cli/src/cli/core/managed-file.ts |
+41 −0 |
packages/squad-cli/src/cli/core/mcp-root.ts |
+18 −14 |
packages/squad-cli/src/cli/core/mcp-spec.ts |
+17 −5 |
packages/squad-cli/src/cli/core/upgrade.ts |
+27 −16 |
packages/squad-sdk/src/casting/durable-registry.ts |
+364 −14 |
packages/squad-sdk/src/casting/index.ts |
+1 −0 |
packages/squad-sdk/src/config/team-capabilities.ts |
+2 −1 |
test/casting-legacy-migration.test.ts |
+489 −0 |
test/cli/legacy-casting-upgrade.test.ts |
+208 −0 |
test/cli/upgrade-portability.test.ts |
+181 −0 |
test/fixtures/casting-assigned-at/history.json |
+13 −0 |
test/fixtures/casting-assigned-at/registry.json |
+11 −0 |
test/fixtures/casting-entries/history.json |
+10 −0 |
test/fixtures/casting-entries/identities.json |
+16 −0 |
test/fixtures/casting-entries/registry.json |
+18 −0 |
test/fixtures/casting-incomplete-universe/history.json |
+13 −0 |
test/fixtures/casting-incomplete-universe/registry.json |
+17 −0 |
test/fixtures/casting-legacy/history.json |
+23 −0 |
test/fixtures/casting-legacy/registry.json |
+20 −0 |
test/mcp-root-write.test.ts |
+34 −0 |
test/mcp-spec-init.test.ts |
+49 −1 |
test/team-capabilities-lifecycle.test.ts |
+15 −0 |
Total: +1732 −65
This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.
🟠 Impact Analysis — PR #2190Risk tier: 🟠 HIGH 📊 Summary
🎯 Risk Factors
📦 Modules Affecteddocs (2 files)
root (3 files)
squad-cli (5 files)
squad-sdk (3 files)
tests (15 files)
|
🏗️ Architectural Review
Automated architectural review — informational only. |
There was a problem hiding this comment.
🟡 Changes recommended
The managed-file binary heuristic can corrupt valid UTF-8 binary assets when adapting line endings.
1 open finding
What changed in this PR
Fixes legacy casting upgrades while improving MCP portability and preserving line endings across managed files.
Changes:
- Migrates and archives supported legacy casting state before upgrades.
- Writes portable project MCP commands while retaining custom metadata.
- Preserves destination newline styles during upgrades.
| File | Description |
|---|---|
test/team-capabilities-lifecycle.test.ts |
Tests CRLF capability refreshes. |
test/mcp-spec-init.test.ts |
Tests portable MCP commands. |
test/mcp-root-write.test.ts |
Tests MCP metadata and CRLF preservation. |
test/fixtures/casting-legacy/registry.json |
Adds legacy registry fixture. |
test/fixtures/casting-legacy/history.json |
Adds legacy history fixture. |
test/cli/upgrade-portability.test.ts |
Tests portable upgrades and managed files. |
test/cli/legacy-casting-upgrade.test.ts |
Tests upgrade migration preflight. |
test/casting-legacy-migration.test.ts |
Tests migration validation and durability. |
packages/squad-sdk/src/config/team-capabilities.ts |
Preserves coordinator line endings. |
packages/squad-sdk/src/casting/index.ts |
Exports casting preflight API. |
packages/squad-sdk/src/casting/durable-registry.ts |
Implements legacy casting migration. |
packages/squad-cli/src/cli/core/upgrade.ts |
Integrates migration and managed writes. |
packages/squad-cli/src/cli/core/mcp-spec.ts |
Projects portable MCP commands. |
packages/squad-cli/src/cli/core/mcp-root.ts |
Preserves MCP custom fields and newlines. |
packages/squad-cli/src/cli/core/managed-file.ts |
Adds newline-aware file helpers. |
packages/squad-cli/src/cli/core/init.ts |
Uses portable MCP specifications. |
docs/src/content/docs/scenarios/upgrading.md |
Documents migration and newline behavior. |
docs/src/content/docs/features/standalone-install.md |
Documents PATH-based MCP launching. |
.changeset/portable-mcp-preserve-newlines.md |
Records portability and newline fixes. |
.changeset/legacy-casting-upgrade.md |
Records casting migration behavior. |
🧠 Review effort: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Require explicit known-text extensions before preserving destination newlines. Cover valid UTF-8 binary payloads without NUL bytes over existing CRLF files, unknown extensions, and known-text update/no-op behavior. Closes #2174 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: cd73060d-2a21-4bce-b8d6-c7507887dbe7
Cross-repository upgrade testing: three remaining legacy compatibility gapsPublishing the findings here so they are visible on GitHub; the earlier inline comments were only local pending-review drafts and were not submitted. Tested PR commit 1. Octosquad:
|
Independent state-storage revision: map entries/assignments through unambiguous authoritative folder/charter identities, retain historical membership and dates, accept assigned_at with conflict detection, and provide actionable recovery refusals for incomplete universe evidence. Add anonymized native-shaped regressions and recovery documentation. Closes #2174 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> Copilot-Session: cd73060d-2a21-4bce-b8d6-c7507887dbe7
|
@bradygaster Thanks for the pinned repros and access. I’ve pushed the independently revised converter in 75bfec3. Octosquad now passes dry-run, upgrade, and repeat upgrade on an unchanged disposable copy of the pinned snapshot. The entries/assignments format uses validated folder/charter identity evidence rather than slugifying display names; historical membership comes from each recorded assignment, not today’s roster. Original dates and byte-exact archives are preserved. PlanningSquad’s unchanged pinned input also passes all three runs. Snapshot and usage conversion now accepts assigned_at and rejects disagreements among recognized timestamp fields. Exact archives and historical dates are preserved. BradyBlogSquad remains explicitly unsupported for automatic migration: the pinned input lacks sufficient universe and usage evidence. Dry-run, upgrade, and repeat stop before file changes with actionable recovery guidance. We do not fill in a universe or fabricate historical usage. The docs describe recovering original assignment/coordinator evidence from backups or version control and keeping the installed version if that evidence is unavailable. This is a verified safe refusal, not a successful migration. These checks ran on Windows, including Octosquad/PlanningSquad CRLF and custom-MCP derived cases that actually reached migration. BradyBlogSquad’s custom-MCP case also remains unchanged on refusal. All private consumer input stays in private artifacts; committed fixtures are anonymized. Build/type checks passed. Fifteen focused suites passed 357 tests (one existing skip and one TODO); ESLint passed with zero errors and 2248 warnings. The seven-release 0.10.0–1.0.1 rerun passed all 20 genuine producer cases and 21 separate supplemental cases. Existing dependency-restore/runtime caveats still apply; this does not claim macOS execution or an exact CI restore. No merge, rebase, or squash was performed. The shared temporary workaround was not changed. |

Summary
Fixes #2174 and #2182.
Automatically migrates supported legacy casting state before upgrade-managed files are changed. Preserves agent identities and historical dates, archives original casting files unchanged, and rejects inconsistent or unsupported input before upgrade writes.
Also prevents machine-specific executable paths in shared MCP configuration and preserves existing line endings during upgrades, including coordinator capability refreshes and backups.
Validation
Tested official checksum-verified Windows releases 0.13.0 and 0.13.1 using actual released initialization and casting writers.
Six genuine released-state cases reproduce the 1.0.1 failure and successfully upgrade with this fix. Six additional anonymized legacy-format cases pass separately.
Verified identity/date/archive preservation, mutation-free dry runs, repeat upgrades, CRLF preservation, newline-only no-op behavior, portable MCP configuration, preserved custom metadata, and invalid-input rejection before upgrade changes.
Build/type checking and ESLint passed. Fifteen targeted test suites passed: 313 tests, one existing skip, and one TODO.
Dependency caveat: Microsoft CFS did not provide locked @types/node 26.6.4. Local validation temporarily used 26.6.3; tracked manifests and the lockfile remain unchanged.